# -*- coding: utf-8 -*-
# created on 2016/9/23


from mathsolver.functions.base import *
from sympy.abc import x, y
from mathsolver.functions.root.jiefangchenzu import JieFangChenZu
from mathsolver.functions.zhixian.base import ZhiXian
from sympy import Abs
from mathsolver.functions.zhixian.property import GetZhongDian
from mathsolver.functions.zhixian.fangcheng import SolveFangChengLiangDian
from mathsolver.functions.zhixian.fangcheng import SolveFangCheng006


# 求直线恒过的定点
class GraphFixedPoint(BaseFunction):
    """
    直线l:kx-y+2k+1=0必过定点().
    """
    def solver(self, *args):
        f1, f2 = args[0].sympify()
        expr = (f1 - f2).expand().simplify()
        symbols = expr.free_symbols
        target = list(symbols.difference([x, y]))
        if len(target) == 1:
            eq_factor = (f1 - f2).factor(target[0])
            self.steps.append(["将直线方程变形为", BaseEq([eq_factor, S.Zero]).printing()])
            a, h = eq_factor.as_independent(target[0])
            target_coeff = h.coeff(target[0])
            self.steps.append(["", BaseEqs([[target_coeff, S.Zero], [a, S.Zero]]).printing()])
            eqs = [[target_coeff, S.Zero], [a, S.Zero]]
        elif len(target) == 2:
            eq_factor0 = expr.factor(target[0])
            a0, h0 = eq_factor0.as_independent(target[0])
            eq_factor1 = expr.factor(target[1])
            a1, h1 = eq_factor1.as_independent(target[1])
            remain_expr = expr - h0 - h1
            self.steps.append(
                ["", "将直线方程变形为%s + %s +%s = 0" % (new_latex(h0), new_latex(h1), new_latex(remain_expr))])
            eqs = [[h0 / target[0], S.Zero], [h1 / target[1], S.Zero]]
            self.steps.append(["", BaseEqs(eqs).printing()])
        else:
            raise Exception("to do")
        stepsolver = JieFangChenZu().solver(BaseEqs(eqs))
        self.steps += stepsolver.steps
        jies = stepsolver.output[0].value
        jies_keys = list(jies.keys())
        if jies_keys[0] == x:
            x_axis = jies[jies_keys[0]].args[0]
            y_axis = jies[jies_keys[1]].args[0]
        else:
            x_axis = jies[jies_keys[1]].args[0]
            y_axis = jies[jies_keys[0]].args[0]
        self.steps.append(["", "直线恒过的定点为(%s,%s)" % (new_latex(x_axis), new_latex(y_axis))])
        self.output.append(BasePoint({"name": "", "value": [x_axis, y_axis]}))
        self.label.add("直线恒过定点问题")
        return self


# 三点共线问题
class SanDianGongXian(BaseFunction):
    """
    若A(1,-3),B(8,-1),C(2a-1,a+2)三点共线,则a=().
    """
    def solver(self, *args):
        if isinstance(args[0], BaseMultiple) and args[0].type == 'Points':
            point0_name = args[0].objs[0].name
            point1_name = args[0].objs[1].name
            point2_name = args[0].objs[2].name
            points_value = args[0].sympify()
            point0_value = points_value[0]
            point1_value = points_value[1]
            point2_value = points_value[2]
        else:
            raise Exception("to do")
        vector1 = (point1_value[0] - point0_value[0], point1_value[1] - point0_value[1])
        vector2 = (point2_value[0] - point0_value[0], point2_value[1] - point0_value[1])
        self.steps.append(["", "%s和%s两点的向量为%s" % (new_latex(point0_name), new_latex(point1_name), new_latex(vector1))])
        self.steps.append(["", "%s和%s两点的向量为%s" % (new_latex(point0_name), new_latex(point2_name), new_latex(vector2))])
        self.steps.append(["", "∵%s, %s 和 %s 三点共线" % (new_latex(point0_name), new_latex(point1_name), new_latex(point2_name))])
        self.steps.append(["", "(%s)*(%s) = (%s)*(%s)" % (new_latex(vector1[0]), new_latex(vector2[1]), new_latex(vector1[1]), new_latex(vector2[0]))])
        self.output.append(BaseEq([vector1[0] * vector2[1], vector1[1] * vector2[0]]))
        self.label.add("三点共线问题")
        return self


# 证明三点共线
class ProveSanDianGongXian(BaseFunction):
    def solver(self, *args):
        points = args[0].sympify()
        point0 = points[0]
        point1 = points[1]
        point2 = points[2]
        vector1 = (point1[0] - point0[0], point1[1] - point0[1])
        vector2 = (point2[0] - point0[0], point2[1] - point0[1])
        self.steps.append(["", "(%s,%s)与(%s,%s)两点的向量为(%s,%s)" % (new_latex(point0[0]), new_latex(point0[1]), new_latex(point1[0]), new_latex(point1[1]), new_latex(vector1[0]), new_latex(vector1[1]))])
        self.steps.append(["", "(%s,%s)与(%s,%s)两点的向量为(%s,%s)" % (new_latex(point0[0]), new_latex(point0[1]), new_latex(point2[0]), new_latex(point2[1]), new_latex(vector2[0]), new_latex(vector2[1]))])
        self.steps.append(["", "∵ (%s)×(%s) = (%s)×(%s) = %s" % (new_latex(vector1[0]), new_latex(vector2[1]),
                                                                 new_latex(vector1[1]), new_latex(vector2[0]),
                                                                 new_latex(vector1[0] * vector2[1]))])
        self.steps.append(["", "∴ 三点共线"])
        self.label.add("证明三点共线")
        return self


# 求直线与坐标轴围成的三角形面积
class ZhiXian002(BaseFunction):
    def solver(self, *args):
        zhixian = args[0].sympify()
        axis_points = ZhiXian(BaseEq(zhixian)).AxisPoints.sympify()
        self.steps.append(["", "直线与坐标轴的交点坐标为%s, %s" % (new_latex(axis_points[0]), new_latex(axis_points[1]))])
        s = Abs(axis_points[0][0]) * Abs(axis_points[1][1]) / 2
        self.steps.append(["", "∴面积S=%s" % (new_latex(s))])
        return self


# △ABC中,A(-2,0)、B(2,0)、C(3,3),则AB边的中线对应方程为()
class ZhiXian003(BaseFunction):
    def solver(self, *args):
        p1, p2 = args[0].name
        point1 = self.search(p1)
        point2 = self.search(p2)
        flag = False
        point3 = None
        for item in self.known:
            if item != p1 and item != p2:
                point3 = self.search(item)
                if isinstance(point3, BasePoint):
                    flag = True
                if flag:
                    break
        stepsolver1 = GetZhongDian().solver(point1, point2)
        self.steps += stepsolver1.steps
        zhongdian = stepsolver1.output[0]
        stepsolver2 = SolveFangChengLiangDian().solver(point3, zhongdian)
        self.steps += stepsolver2.steps
        self.label.add("求三角形边的中线方程")
        return self


# 三角形的三个顶点是A(-1,0)、B(3,-1)、C(1,3).求BC边上的高所在直线的方程
class ZhiXian004(BaseFunction):
    def solver(self, *args):
        p1, p2 = args[0].name
        point1 = self.search(p1)
        point1 = point1.sympify()
        point2 = self.search(p2)
        point2 = point2.sympify()
        sanjiao = set('ABC')
        p1_set = set(p1)
        p2_set = set(p2)
        p3 = sanjiao.difference(p1_set)
        p3 = p3.difference(p2_set)
        p3 = list(p3)[0]
        point3 = self.search(p3)
        point3 = point3.sympify()
        vector = [point1[0] - point2[0], point1[1] - point2[1]]
        fa_vetor = BaseVector({"name": "", "value": vector})
        self.steps.append(["", "∴经过点%s和点%s的向量为%s" % (BasePoint({"name": p1, "value": point1}).printing(), BasePoint({"name": p2, "value": point2}).printing(), BaseVector({"name": "", "value": vector}).printing())])
        stepsolver = SolveFangCheng006().solver(fa_vetor, BasePoint({"name": "", "value": point3}))
        self.steps += stepsolver.steps
        self.label.update(stepsolver.label)
        self.output.append(stepsolver.output[0])
        self.label.add("求三角形高所在的直线方程")
        return self


# 直线与直线相同:-ax-3y-9=0 与 x-3y+b=0 是同一直线
class ZhiXian007(BaseFunction):
    """
    直线ax+3y-9=0与直线x-3y+b=0关于原点对称,则a、b的值分别为()
    """
    def solver(self, *args):
        zhixian1 = args[0].sympify()
        zhixian2 = args[1].sympify()
        zhixian1_a, zhixian1_b, zhixian1_c = ZhiXian(BaseEq([zhixian1[0], zhixian1[1]])).get_coeff()
        zhixian2_a, zhixian2_b, zhixian2_c = ZhiXian(BaseEq([zhixian2[0], zhixian2[1]])).get_coeff()
        a1 = zhixian1_a.sympify()
        b1 = zhixian1_b.sympify()
        c1 = zhixian1_c.sympify()
        a2 = zhixian2_a.sympify()
        b2 = zhixian2_b.sympify()
        c2 = zhixian2_c.sympify()
        eqs = [[a1 * b2, a2 * b1], [a1 * c2, a2 * c1], [b1 * c2, b2 * c1]]
        self.steps.append(["", "∵%s = %s 和 %s = %s是同一直线，得" % (new_latex(zhixian1[0]), new_latex(zhixian1[1]), new_latex(zhixian2[0]), new_latex(zhixian2[1]))])
        self.steps.append(["∴", BaseEqs(eqs).printing()])
        self.output.append(BaseEqs(eqs))
        self.label.add("两直线相等的条件")
        return self


# 点与点相等
class PointEqualPoint(BaseFunction):
    def solver(self, *args):
        point1 = args[0].sympify()
        point2 = args[1].sympify()
        self.steps.append(["", "∵%s和%s是同一点" % (BasePoint({"name": "", "value": point1}).printing(), BasePoint({"name": "", "value": point2}).printing())])
        eqs = [[point1[0], point2[0]], [point1[1], point2[1]]]
        self.steps.append(["", "∴%s" % (BaseEqs(eqs).printing())])
        self.output.append(BaseEqs(eqs))
        return self


# 线段与直线相交问题
class LineIntersectSegment001(BaseFunction):
    def solver(self, *args):
        if len(args) == 2 and isinstance(args[0], BaseLine):
            line_name = args[0].name
            left, right = line_name
            point1 = self.search(left)
            point1 = point1.sympify()
            point2 = self.search(right)
            point2 = point2.sympify()
            eq = args[1].sympify()
        expr = (eq[0] - eq[1]).expand().simplify()
        new_expr1 = expr.subs({x: point1[0], y: point1[1]})
        new_expr2 = expr.subs({x: point2[0], y: point2[1]})
        self.steps.append(["", "∵直线%s与线段%s相交，得" % (BaseZhiXian({"name": "", "value": eq}).printing(), new_latex(line_name))])
        ineq = [new_expr1 * new_expr2, "<=", S.Zero]
        self.steps.append(["", "(%s) * (%s) <= 0" % (new_latex(new_expr1), new_latex(new_expr2))])
        self.output.append(BaseIneq(ineq))
        self.label.add("线段与直线相交问题")
        return self


class LineIntersectSegment002(BaseFunction):
    """
    已知点A(1,3)和点B(5,2)分别在直线3x+2y+a=0的两侧,则实数a的取值范围为.
    """
    def solver(self, *args):
        if len(args) == 3 and isinstance(args[0], BasePoint):
            point1 = args[0].sympify()
            point2 = args[1].sympify()
            eq = args[2].sympify()
        else:
            raise Exception("to do")
        expr = (eq[0] - eq[1]).expand().simplify()
        new_expr1 = expr.subs({x: point1[0], y: point1[1]})
        new_expr2 = expr.subs({x: point2[0], y: point2[1]})
        self.steps.append(["", "∵点%s与点%s在直线%s两侧" % (BasePoint({"name": "", "value": point1}).printing(), BasePoint({"name": "", "value": point2}).printing(), BaseZhiXian({"name": "", "value": eq}).printing())])
        ineq = [new_expr1 * new_expr2, "<=", S.Zero]
        self.steps.append(["", "(%s) * (%s) <= 0" % (new_latex(new_expr1), new_latex(new_expr2))])
        self.output.append(BaseIneq(ineq))
        self.label.add("两点在直线两侧问题")
        return self


if __name__ == '__main__':
    pass
